#pragma once
#include <d3dx9.h>
#define D3DX_2PI 6.283185308f

#define CAMERA_SPEED 100.0f

enum CameraModes
{
	OPEN_WORLD_CAMERA = 0,
	COMBAT_CAMERA
};

class CCamera
{
private:
	bool m_bGround_Clamp;	// Enable/Disable Ground Clamping (Default 50 units)
	D3DXVECTOR3 m_position; // camera position
	bool m_bInvertY;		// Invert mouse look?
	POINT m_LastMousePosition; //in "process camera" we do our mouse movement based on the mouse movement.

	float RestrictAngleTo360Range(float angle) const;

	int m_nCameraMode;
public:
	float m_mouseDiff[2];
	float m_yaw;			// rotation around the y axis
	float m_pitch;			// rotation around the x axis
	float m_roll;			// rotation around the z axis
	D3DXVECTOR3 m_up,m_look,m_right; // camera axes
	D3DXMATRIX m_ProjectionMatrix;
	bool m_bCursorLock;
	CCamera();
	~CCamera(void);

	void CalculateViewMatrix(D3DXMATRIX *viewMatrix);

	// Gets
	float GetYaw() const {return m_yaw;}
	float GetPitch() const {return m_pitch;}
	float GetRoll() const {return m_roll;}
	D3DXVECTOR3 GetPosition() const {return m_position;}	
	D3DXVECTOR3 GetLook() const {return m_look;}
	
	// Sets
	void SetPosition(const D3DXVECTOR3& pos) { m_position = pos; }
	void SetInverted(const bool bInvertY) { m_bInvertY = bInvertY; }

	// Move operations
	void MoveForward(float amount) {m_position+=m_look*amount;}
	void MoveRight(float amount) {m_position+=m_right*amount;}
	void MoveUp(float amount) {m_position+=m_up*amount;}

	// Rotations
	void Yaw(float amount); // rotate around x axis
	void Pitch(float amount); // rotate around x axis
	void Roll(float amount); // rotate around z axis
	static CCamera* GetInstance(void);

	void TurnTo( D3DXMATRIX &CameraMatrix, const D3DXVECTOR3 &Target, float fTime );
	void Initialize(IDirect3DDevice9* pDevice, D3DXVECTOR3 startPosition, int nScreenWidth,int nScreenHeight, float fNearClip, float fFarClip);
	
	void ProcessCamera(float fTime);
	void OpenWorldCamera(float fTime);
	void CombatCamera(float fTime);

	inline void SetCameraMode(int nMode) {m_nCameraMode = nMode;}
};

inline CCamera* Camera(void)
{
	return CCamera::GetInstance();
}